package com.maiji.cloud.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.google.common.collect.Lists;
import com.maiji.cloud.entities.login.UserInfo;
import com.maiji.cloud.entities.shopingmall.CapitalIOEntity;
import com.maiji.cloud.entities.shopingmall.CapitalMain;
import com.maiji.cloud.entities.shopingmall.WithdrawApply;
import com.maiji.cloud.mapper.WithdrawApplyMapper;
import com.maiji.cloud.microservice.UserInfoService;
import com.maiji.cloud.request.ReqMetaData;
import com.maiji.cloud.response.*;
import com.maiji.cloud.service.CapitalIOService;
import com.maiji.cloud.service.CapitalMainService;
import com.maiji.cloud.service.WithdrawApplyService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.maiji.cloud.utils.*;
import org.apache.commons.lang3.BooleanUtils;
import org.eclipse.jetty.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional
public class WithdrawApplyServiceImpl extends ServiceImpl<WithdrawApplyMapper, WithdrawApply> implements WithdrawApplyService {

    Logger logger = LoggerFactory.getLogger(WithdrawApplyServiceImpl.class);
    @Value("${apnsProduction}")
    private Boolean apnsProduction;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private CapitalMainService capitalMainService;
    @Autowired
    private CapitalIOService capitalIOService;

    @Override
    public BaseMetaResDto<List<WithdrawApply>> findAllWithdrawApplys(WithdrawApply data, ReqMetaData metaData) {
        EntityWrapper<WithdrawApply> entityWrapper = new EntityWrapper<>();
        String nickName = data.getNickName();
        List<UserInfo> userInfos = Lists.newArrayList();
        if (StringUtil.isNotBlank(nickName)) {
            userInfos = userInfoService.selectList(nickName);
            if (userInfos.size() > 0) entityWrapper.eq("user_id", userInfos
                    .parallelStream().map(UserInfo::getUserId).collect(Collectors.toList()));
        }
        if (StringUtil.isNotBlank(data.getRealName())) entityWrapper.like("real_name", data.getRealName());
        if (data.getExamine() != null) entityWrapper.eq("examine", data.getExamine());
        List<Date> applyDates = data.getApplyDates();
        if (applyDates != null && applyDates.size() > 0) {
            entityWrapper.ge("apply_date", applyDates.get(0));
            if (applyDates.size() > 1) entityWrapper.ge("apply_date", applyDates.get(1));
        }
        List<Date> examineDates = data.getExamineDates();
        if (examineDates != null && examineDates.size() > 0) {
            entityWrapper.ge("examine_date", examineDates.get(0));
            if (examineDates.size() > 1) entityWrapper.ge("examine_date", examineDates.get(1));
        }
        Page<WithdrawApply> page = selectPage(new Page<>(metaData.getPage(), metaData.getSize()), entityWrapper);
        List<WithdrawApply> withdrawApplies = page.getRecords();
        if (withdrawApplies.size() > 0) {
            if (userInfos.size() == 0) userInfos = userInfoService.selectList(withdrawApplies
                    .parallelStream().map(WithdrawApply::getUserId).collect(Collectors.toList()));
            withdrawApplies = BaseService.dealWithOneToOne(withdrawApplies, "getUserId",
                    WithdrawApply.class,"setUserInfo", userInfos, "getUserId", UserInfo.class);
        }
        ResMetaData resMetaData = new ResMetaData(page.getCurrent(), page.getSize(), page.getTotal());
        return new BaseMetaResDto<List<WithdrawApply>>(Status.SUCCESS).setData(withdrawApplies).setResMetaData(resMetaData);
    }

    @Override
    public BaseResDto examineWithdrawApply(WithdrawApply data) {
        if (data.getExamine() == 1) { // 审核通过
            CapitalIOEntity capitalIOEntity = new CapitalIOEntity().setUuId(UUID_MD5.getUUID()).setIoMoney(data.getMoney())
                    .setStart(CommonIntValueEnum.WITHDRAWDISTRIBUTION.getValue()).setInTime(new Date())
                    .setMoney(data.getMoney()).setUserId(data.getUserId()).setType(CommonIntValueEnum.CAPITAL_TYPE_OUT.getValue());
            if (data.getType() == 1)  // 提现到支付宝
                try {
                    AlipayFundTransToaccountTransferResponse reponse = AlipayUtil.alipayWithdraw(data.getCapitalIoId(),
                            data.getRealName(), data.getAccount(), data.getIoMoney());
                    logger.info("examineWithdrawApply.examineWithdrawApply ===>> Alipay ===>> reponse = {}", JSON.toJSONString(reponse));
                    if (! "10000".equals(reponse.getCode())) return new BaseResDto(Status.ERROR, "提现到支付宝失败");
                    capitalIOEntity.setEnd(CommonIntValueEnum.ALIPAY.getDescription());
                } catch (AlipayApiException e) {
                    e.printStackTrace();
                }
            if (data.getType() == 2)  // 提现到微信
                try {
                    Map map = WXUtil.wxWithdraw(data.getAccount(), data.getRealName(), data.getIoMoney());
                    logger.info("examineWithdrawApply.examineWithdrawApply ===>> WX ===>> reponse = {}",JSON.toJSONString(map));
                    if(! ("SUCCESS".equals(map.get("return_code")) && "SUCCESS".equals(map.get("result_code"))) )
                        return new BaseResDto(Status.ERROR, "提现到微信失败");
                    capitalIOEntity.setEnd(CommonIntValueEnum.WEIXIN.getDescription());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            if (! capitalIOService.insert(capitalIOEntity)) return new BaseResDto(Status.ERROR.setMessage("记录提现流水失败"));
            JpushUtil.sendToAlias(data.getUserId(), "您的分销金额已提现成功，请注意核实资金账户信息", apnsProduction);
        }
        if (data.getExamine() == 2) { // 审核拒绝
            CapitalMain capitalMain = capitalMainService.selectOne(new EntityWrapper<CapitalMain>().eq("user_id", data.getUserId()));
            capitalMain.setDistributionMoney(NumberUtil.add(capitalMain.getDistributionMoney(), data.getIoMoney()));
            if (! capitalMainService.updateById(capitalMain)) return new BaseResDto(Status.ERROR.setMessage("修改用户资金账户失败"));
            JpushUtil.sendToAlias(data.getUserId(), "抱歉，您的分销金额提现失败，请联系客服进行咨询", apnsProduction);
        }
        if (! updateById(data.setOperatorDate(new Date()))) return new BaseResDto(Status.ERROR.setMessage("审核提现申请失败"));
        return new BaseResDto(Status.SUCCESS);
    }

}
